#include "esp_01s_mqtt.h"
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//only debug
#include "bsp_uart.h"
#define debug_printf(fmt, ...) //UARTx_Printf(&huart1, fmt, ##__VA_ARGS__)

const uint8_t ESP_01S_CONNECT_TYPE[ESP_01S_MAX_CONNECT_TYPE][4] = {"TCP","UDP","SSL"};

#define ESP_01S_CMD_RST         "AT+RST\r\n"
#define ESP_01S_CMD_WMODE_GET   "AT+CWMODE?\r\n"//+CWSTATE:<state>,<"ssid">
    #define prefix_cwmode       "+CWMODE:"
#define ESP_01S_CMD_WMODE_SET1  "AT+CWMODE=%d\r\n"//AT+CWMODE=<mode>[,<auto_connect>]
#define ESP_01S_CMD_WMODE_SET2  "AT+CWMODE=%d,%d\r\n"

#define ESP_01S_CMD_IPSTA_GET   "AT+CIPSTA?\r\n"
    #define prefix_ip           "+CIPSTA:ip:\""
    #define prefix_gateway      "+CIPSTA:gateway:\""
    #define prefix_netmask      "+CIPSTA:netmask:\""
#define ESP_01S_CMD_PING        "AT+PING=\"%s\"\r\n"
    #define prefix_ping         "+PING:"
#define ESP_01S_CMD_JAP         "AT+CWJAP=\"%s\",\"%s\"\r\n"
    #define prefix_jap_connected    "WIFI CONNECTED"
    #define prefix_jap_got_ip       "WIFI GOT IP"
#define ESP_01S_CMD_JAP_BSSID   "AT+CWJAP=\"%s\",\"%s\",\"%s\"\r\n"
#define ESP_01S_CMD_SAP         "AT+CWSAP=\"%s\",\"%s\",%d,%d\r\n"
#define ESP_01S_CMD_CIPSTART    "AT+CIPSTART=\"%s\",\"%s\",%d,%d\r\n"
    #define prefix_connect      "CONNECT"
#define ESP_01S_CMD_CIPCLOSE    "AT+CIPCLOSE\r\n"
#define ESP_01S_CMD_CIPSEND     "AT+CIPSEND=%d\r\n"
#define ESP_01S_CMD_PASSTHROUGH "AT+CIPSEND\r\n"
#define ESP_01S_CMD_CIPMODE     "AT+CIPMODE=%d\r\n"
#define ESP_01S_REQ_END         "OK\r\n"
#define ESP_01S_REQ_ERROR       "ERROR\r\n"

#define ESP_01S_CMD_MQTT_USERCFG    "AT+MQTTUSERCFG=0,%d,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n"
#define ESP_01S_CMD_MQTT_CONNECT    "AT+MQTTCONN=0,\"%s\",%d,0\r\n"
// AT+MQTTSUB=<LinkID>,<"topic">,<qos>
#define ESP_01S_CMD_MQTT_SUBSCRIBE  "AT+MQTTSUB=0,\"%s\",0\r\n"
// AT+MQTTPUB=<LinkID>,<"topic">,<"data">,<qos>,<retain>
#define ESP_01S_CMD_MQTT_PUBLISH   "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n"

/**
 * @brief 复制数据直到指定大小或结束符
 * @param dst 目的地址
 * @param src 源地址
 * @param size 复制最大尺寸
 * @param stopChar 停止符
 * @retval int 
 */
int copy_until_stopChar(uint8_t *dst, const uint8_t *src, uint16_t size, char stopChar)
{
    if (dst == NULL) return 0;
    size_t i = 0;
    while(i < size && src[i] != stopChar)
    {
        dst[i] = src[i];
        i++;
    }
    return i;
}

//static uint8_t ipv4_to_string(uint32_t ip, char *ip_str, uint8_t ip_str_size)
//{
//    // Convert ipv4 to string format
//    // Example: 192.168.111.111 -> "192.168.111.111" , len = 3*4+3 = 15
//    uint8_t len = 0;
//    len = snprintf(ip_str, ip_str_size, "%d.%d.%d.%d", ip_str[0], ip_str[1], ip_str[2], ip_str[3]);
//    return len;
//}


/**
 * @brief 寻找数据子串
 * @param pdata 数据指针
 * @param size 数据长度
 * @param subdata 子数据指针
 * @param subdatasize 子串长度 
 * @retval uint8_t* 
 */
uint8_t *find_subData(const uint8_t *pdata, uint8_t size, const void *psubdata, uint8_t subdatasize)
{
    int i, j = 0;
	uint8_t *subdata = (uint8_t*) psubdata;
    // 搜索子数据串 "abcdeefght" "cde1"
    for (i = 0; i < size; i++)
    {
        if (pdata[i] == subdata[j])
        {
            j++;
            if (j == subdatasize)
            {
                return (uint8_t*)(pdata + i - subdatasize + 1);
            }
        }
        else
        {
            if (size - i < subdatasize) break;
            i -= j;
            j = 0;
        }
    }
	return NULL;
}

void esp01s_reset(esp_01s_mqtt_t *pesp01s)
{
    pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_RST, sizeof(ESP_01S_CMD_RST) - 1);

}

/**
 * @brief 请求获取无线模式
 * @param pesp01s 
 * @retval int 0:失败 / 1:成功
 */
int esp01s_get_wirless_mode_request(esp_01s_mqtt_t *pesp01s)
{
    if (pesp01s == NULL || pesp01s->request_state != 0) return 0;
    pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_WMODE_GET, sizeof(ESP_01S_CMD_WMODE_GET) - 1);
    return pesp01s->request_state = ESP_01S_REQ_WMODE_GET_STATE;
}

/**
 * @brief 解析获取无线模式请求的回复
 * @param pdata 
 * @param size 
 * @param state 
 * @retval int OK:0 / Failure:-1
 */
int esp_01s_get_wirless_mode(uint8_t *pdata, uint8_t size, uint8_t *state)
{
    if (pdata == NULL || size < 29 || state == NULL) return -1;
    uint8_t *p = NULL;
    /* 回应格式
        AT+CWMODE?\r\n+CWMODE:1\r\n\r\nOK\r\n
    */
    p = pdata + 12;
    p = find_subData(p, size - 10, (uint8_t*)prefix_cwmode, sizeof(prefix_cwmode) - 1);
    if (p == NULL) return -1;
    p += sizeof(prefix_cwmode) - 1;
    if (*p == 'T') //Timeout
    {
        *state = 255;
    }
    else
    {
        *state = p[0] - '0';
    }
	return 0;
}


/**
 * @brief 无线模式设置
 * @note 切换 ESP32 设备的 Wi-Fi 模式时（例如，从 SoftAP 或无 Wi-Fi 模
         式切换为 Station 模式或 SoftAP+Station 模式），是否启用自动连接
         AP 的功能，默认值：1。参数缺省时，使用默认值，也就是能自动连接。
 * @param pesp01s 
 * @param mode 
 *          0: 无 Wi-Fi 模式，并且关闭 Wi-Fi RF
 *          1: Station 模式
 *          2: SoftAP 模式
 *          3: SoftAP+Station 模式
 * @param auto_connect 
 *          0: 禁用自动连接 AP 的功能
 *          1: 启用自动连接 AP 的功能，若之前已经将自动连接 AP 的配置保
 *             存到 flash 中，则设备将自动连接 AP
 *          >=2: 保持上次设置
 * @retval int 
 */
int esp01s_set_wirless_mode(esp_01s_mqtt_t *pesp01s, uint8_t mode, uint8_t auto_connect)
{
    pesp01s->request_state = ESP_01S_REQ_STATE;
    if (auto_connect >= 2)
    {
        return pesp01s->uart_tx_printf(ESP_01S_CMD_WMODE_SET1, mode);
    }
    return pesp01s->uart_tx_printf(ESP_01S_CMD_WMODE_SET2, mode, auto_connect);
}

/**
 * @brief 请求获取ip相关状态
 * @param pesp01s 
 * @retval int 0:失败 / 1:成功
 */
int esp01s_get_ip_state_request(esp_01s_mqtt_t *pesp01s)
{
    if (pesp01s == NULL || pesp01s->request_state != 0) return 0;
    // request
    pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_IPSTA_GET, sizeof(ESP_01S_CMD_IPSTA_GET) - 1);
   return pesp01s->request_state = ESP_01S_REQ_IPSTA_GET_STATE;
}
/**
 * @brief 提供解析数据获取IP相关状态
 * @param data 要解析的数据
 * @param size 解析的数据长度
 * @param ip 存储IP的字符缓冲区
 * @param gateway 存储网关IP的字符缓冲区
 * @param netmask 存储子网掩码的字符缓冲区
 * @retval int 失败:-1/成功:0
 * @note 2024.04.20已测试
 */
static int esp01s_get_ip_state(const uint8_t *pdata, uint16_t size, char *ip, char *gateway, char *netmask)
{
    if (ip == NULL || gateway == NULL || netmask == NULL) return -1;
    if (pdata == NULL || size < 94) return -1;
    /* 回应格式
        AT+CIPSTA?\r\n
        +CIPSTA:ip:"192.168.137.53"\r\n
        +CIPSTA:gateway:"192.168.137.1"\r\n
        +CIPSTA:netmask:"255.255.255.0"\r\n
        \r\nOK\r\n
    */
    // 头尾校验
    if (strncmp((char *)pdata, ESP_01S_CMD_IPSTA_GET, 10) != 0) return -1;
    if (strncmp((char *)pdata + size - 4, ESP_01S_REQ_END, 4) != 0) return -1;
    uint8_t *ptr = (uint8_t*)pdata + 12;
    size_t i = size - 10;
    int cnt = 0;
    // 检验参数数量是否完整 (六个双引号)
    while (i--)
    {
        if (ptr[i] == '"') cnt++;
    }
    if (cnt != 6) return -1;
    // 获取IP字符串
    ptr = find_subData(ptr, size - (ptr - pdata), (uint8_t*)prefix_ip, sizeof(prefix_ip)-1);
    if (ptr == NULL) return -1;
    ptr += sizeof(prefix_ip)-1;
    cnt = copy_until_stopChar((uint8_t*)ip, ptr, 15, '"');
    ip[cnt] = '\0';
    ptr += cnt + 1;
    // 获取网关字符串
    ptr = find_subData(ptr, size - (ptr - pdata), (uint8_t*)prefix_gateway, sizeof(prefix_gateway)-1);
    if (ptr == NULL) return -1;
    ptr += sizeof(prefix_gateway)-1;
    cnt = copy_until_stopChar((uint8_t*)gateway, ptr, 15, '"');
    gateway[cnt] = '\0';
    ptr += cnt + 1;
    // 获取子网掩码字符串
    ptr = find_subData(ptr, size - (ptr - pdata), (uint8_t*)prefix_netmask, sizeof(prefix_netmask)-1);
    if (ptr == NULL) return -1;
    ptr += sizeof(prefix_netmask)-1;
    cnt = copy_until_stopChar((uint8_t*)netmask, ptr, 15, '"');
    netmask[cnt] = '\0';
    return 0;
}

/**
 * @brief ping
 * @param pesp01s 
 * @param ip 
 * @retval int 0:失败 / 1:成功 / -1:繁忙
 */
int esp01s_ping(esp_01s_mqtt_t *pesp01s, const char *ip)
{
    if (pesp01s == NULL || pesp01s->request_state != 0) return 0;
    if (pesp01s->request_state != ESP_01S_REQ_IDLE_STATE) return -1;
    pesp01s->uart_tx_printf(ESP_01S_CMD_PING, ip);
    pesp01s->request_state = ESP_01S_REQ_PING_GET_STATE;
    return 1;
}
/**
 * @brief 解析ping回应
 * @param pdata 回应报文
 * @param size 报文长度
 * @param pingValue 
 * @retval int 0:成功 / -1:失败
 */
static int esp01s_get_ping_value(const uint8_t *pdata, uint16_t size, uint16_t *pingValue)
{
    if (pdata == NULL || size < 20 || pingValue == NULL) return -1;
    uint8_t *ptr;
    /*
        AT+PING="192.168.137.1"\r\n+PING:44\r\n\r\nOK\r\n
        AT+PING="192.168.137.2"\r\n+PING:TIMEOUT\r\n\r\nOK\r\n
    */
    ptr = find_subData(pdata, size, (uint8_t*)prefix_ping, sizeof(prefix_ping)-1);
    if (ptr == NULL) return -1;
    ptr += sizeof(prefix_ping)-1;
    if (strncmp((char*)ptr, "TIMEOUT", 7) == 0) // 超时
    {
        *pingValue = 0xFFFF;
        return 0;
    }
    *pingValue = atoi((char*)ptr);
    return 0;
}

// AT+CWJAP=[<ssid>],[<pwd>][,<bssid>][,<pci_en>][,<reconn_interval>][,<listen_interval>][,<scan_mode>][,<jap_timeout>][,<pmf>]
/**
 * @brief 加入热点
 * @param pesp01s 
 * @param ap_ssid 热点名称
 * @param ap_password 热点密码
 * @param bssid 热点MAC地址
 * @retval int 
 */
int esp01s_join_ap(esp_01s_mqtt_t *pesp01s, const char *ap_ssid, const char *ap_password, const char *bssid)
{
    if(bssid != NULL)
    {
        pesp01s->uart_tx_printf(ESP_01S_CMD_JAP_BSSID, ap_ssid, ap_password, bssid);
    }
    else
    {
        pesp01s->uart_tx_printf(ESP_01S_CMD_JAP, ap_ssid, ap_password);
    }
    pesp01s->request_state = ESP_01S_REQ_JAP_STATE;
	return 0;
}

static int esp01s_get_jap_state(const uint8_t *data, uint16_t size)
{
    if (data == NULL || size < 50) return -1;
    /*
        AT+CWJAP="ssid","password"\r\n
        WIFI DISCONNECT\r\n
        WIFI CONNECTED\r\n
        WIFI GOT IP\r\n
        \r\nOK\r\n
    */
    if (find_subData((uint8_t*)data, size, (uint8_t*)prefix_jap_got_ip, sizeof(prefix_jap_got_ip)-1) != NULL)
    {
        // 连接成功
        return 0;
    }
	return -1;
}

// AT+CWSAP=<ssid>,<pwd>,<chl>,<ecn>[,<max conn>][,<ssid hidden>]
/**
 * @brief 设置softAP参数
 * @param pesp01s 
 * @param station_ssid 
 * @param station_password 
 * @param channel [1 , 13]
 * @param ecn 0: OPEN/ 2: WPA_PSK/ 3: WPA2_PSK/ 4: WPA_WPA2_PSK
 * @retval int 
 */
int esp01s_set_sap(esp_01s_mqtt_t *pesp01s,
                   char *station_ssid,
                   char *station_password,
                   uint8_t channel,
                   uint8_t ecn)
{
    pesp01s->uart_tx_printf(ESP_01S_CMD_SAP, station_ssid, station_password, channel, ecn);
	return 0;
}

// AT+CIPSTART=<"type">,<"remote host">,<remote port>[,<keep_alive>][,<"local IP">]
/**
 * @brief 建立网络连接
 * @param pesp01s 
 * @param type 0:"TCP",1:"UDP",2:"SSL"
 * @param reomte_ip remote ip
 * @param reomte_prot remote port
 * @param local_port local port
 * @param pcallback 
 * @retval int 
 */
int esp01s_connect(esp_01s_mqtt_t *pesp01s,
                   uint8_t type,
                   const char *reomte_ip,
                   uint16_t remote_port,
                   uint16_t local_port,
                   esp_01s_mqtt_callback_t pcallback)
{
    if (type > ESP_01S_MAX_CONNECT_TYPE) return -1;
    pesp01s->uart_tx_printf(ESP_01S_CMD_CIPSTART, ESP_01S_CONNECT_TYPE[type], reomte_ip, remote_port, local_port);
    pesp01s->uart_rx_callback = pcallback;
    pesp01s->request_state = ESP_01S_REQ_CONNECT_STATE;
    return 0;
}

/**
 * @brief 确认连接成功
 * @param pdata 
 * @param size 
 * @retval int 0:成功 / 1:失败
 */
static int esp01s_connect_ack(uint8_t *pdata, uint16_t size)
{
    /*
        AT+CIPSTART="UDP","192.168.4.255",8888,8888,0\r\n
        CONNECT\r\n
        \r\nOK\r\n
    */
   if(pdata == NULL || size < 30) return -1;
    uint8_t *ptr;
    ptr = find_subData(pdata, size, (uint8_t*)prefix_connect, sizeof(prefix_connect)-1);
    if (ptr != NULL)
    {
        return 0;
    }
    return -1;
}

// AT+CIPCLOSE
int esp01s_disconnect(esp_01s_mqtt_t *pesp01s)
{
	uint16_t size;
    pesp01s->uart_rx_callback = NULL;
    size = pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_CIPCLOSE, sizeof(ESP_01S_CMD_CIPCLOSE) - 1);
	pesp01s->receive_state = ESP_01S_RECV_IDLE_STATE;
    return size;
}

// AT+CIPSEND=<length>
int esp01s_send(esp_01s_mqtt_t *pesp01s, uint8_t *data, uint16_t len)
{
    // pesp01s->uart_tx_printf(ESP_01S_CMD_CIPSEND, len);
	return pesp01s->uart_tx(data, len);
}

/**
 * @brief 设置透传模式
 * @param pesp01s 
 * @param state 1:开启透传 / 0:关闭透传
 * @note 使用前需要先使用'esp01s_set_transmit_mode'将传输模式设置为透传
 * @retval int 
 */
int esp01s_set_passthrough(esp_01s_mqtt_t *pesp01s, uint8_t state)
{
	uint16_t size;
    if (state == 1)
    {
        size = pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_PASSTHROUGH, sizeof(ESP_01S_CMD_PASSTHROUGH) - 1);
        pesp01s->request_state = ESP_01S_REQ_PASSTHROUGH_STATE; // 请求开启透传模式
        /* 回复格式
            AT+CIPSEND\r\n\r\nOK\r\n>
        */
    }
    else
    {
        size = pesp01s->uart_tx((uint8_t*)"+++", 3);
        esp01s_request_set_idle(pesp01s);
        pesp01s->receive_state = ESP_01S_RECV_IDLE_STATE;
    }
	return size;
}

/**
 * @brief 设置传输模式
 * @param pesp01s 
 * @param mode 0: 普通传输模式 
 *             1: Wi-Fi 透传接收模式，仅支持 TCP 单连接、UDP 固定通信对端、SSL 单连接的情况
 * @retval int 
 */
int esp01s_set_transmit_mode(esp_01s_mqtt_t *pesp01s, uint8_t mode)
{
    pesp01s->uart_tx_printf(ESP_01S_CMD_CIPMODE, mode);
    pesp01s->request_state = ESP_01S_REQ_STATE;
    return 0;
}

void esp01s_request_set_idle(esp_01s_mqtt_t *pesp01s)
{
    pesp01s->request_state = ESP_01S_REQ_IDLE_STATE;
}

/**
 * @brief 获取当前请求是否完成
 * @param pesp01s 
 * @retval int 1: 完成 / 0: 未完成
 */
int esp01s_request_is_cplt(esp_01s_mqtt_t *pesp01s)
{
    if (pesp01s->request_state == ESP_01S_REQ_CPLT_STATE)
    {
        pesp01s->request_state = ESP_01S_REQ_IDLE_STATE;
        return 1;
    }
    return 0;
}

/**
 * @brief 配置MQTT参数
 * @param pesp01s 
 * @param mqttCfg 
 * @retval int 
 */
int esp01s_mqtt_userConfig(esp_01s_mqtt_t *pesp01s, const mqtt_config_t *mqttCfg)
{
    if (pesp01s == NULL || mqttCfg == NULL) return -1;
    if (mqttCfg->client_id == NULL || mqttCfg->username == NULL || mqttCfg->password == NULL) return -1;
    //AT+MQTTUSERCFG=<LinkID>,<scheme>,<"client_id">,<"username">,<"password">,<cert_key_ID>,<CA_ID>,<"path">
    pesp01s->uart_tx_printf(ESP_01S_CMD_MQTT_USERCFG,
                            mqttCfg->scheme,
                            mqttCfg->client_id,
                            mqttCfg->username,
                            mqttCfg->password);
    return 0;
}

/**
 * @brief 连接MQTT服务器
 * @param pesp01s 
 * @param mqttCfg 
 * @param pcallback 
 * @retval int 
 * @note 需要判断返回的值，确定是否成功连接
 */
int esp01s_mqtt_connect(esp_01s_mqtt_t *pesp01s,
                        const mqtt_config_t *mqttCfg,
                        esp_01s_mqtt_callback_t pcallback)
{
    if (pesp01s == NULL || mqttCfg == NULL) return -1;
    pesp01s->uart_rx_callback = pcallback;
    //AT+MQTTCONN=<LinkID>,<"host">,<port>,<reconnect>
    pesp01s->uart_tx_printf(ESP_01S_CMD_MQTT_CONNECT, mqttCfg->host_ip, mqttCfg->host_port);
    pesp01s->request_state = ESP_01S_REQ_MQTT_CONNECT_STATE;
    return 0;
}

/**
 * @brief 发布MQTT主题
 * @param pesp01s 
 * @param topic 
 * @param data 
 * @retval int 
 */
int esp01s_mqtt_publish(esp_01s_mqtt_t *pesp01s, const char *topic, const char *data)
{
    if (pesp01s == NULL || topic == NULL || data == NULL) return -1;
    // AT+MQTTPUB=<LinkID>,<"topic">,<"data">,<qos>,<retain>
    //"AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n"
    // pesp01s->uart_tx_printf(ESP_01S_CMD_MQTT_PUBLISH, topic, data);
    pesp01s->uart_tx((uint8_t*)ESP_01S_CMD_MQTT_PUBLISH, 14);
    pesp01s->uart_tx((uint8_t*)topic, strlen(topic));
    pesp01s->uart_tx((uint8_t*)"\",\"", 3);
    pesp01s->uart_tx((uint8_t*)data, strlen(data));
    pesp01s->uart_tx((uint8_t*)"\",0,0\r\n", 7);

    return 0;
}

/**
 * @brief 订阅MQTT主题
 * @param pesp01s 
 * @param topic 
 * @retval int 
 */
int esp01s_mqtt_subscribe(esp_01s_mqtt_t *pesp01s, const char *topic)
{
    if (pesp01s == NULL || topic == NULL) return -1;
    // AT+MQTTSUB=<LinkID>,<"topic">,<qos>
    pesp01s->uart_tx_printf(ESP_01S_CMD_MQTT_SUBSCRIBE, topic);
    return 0;
}

int esp01s_uart_rx_callback(esp_01s_mqtt_t *pesp01s, uint8_t *data, uint16_t len)
{
    int state;
    uint8_t *ptr;

    /* 当前在透传状态 */
    if (pesp01s->receive_state == ESP_01S_RECV_PASSTHROUGH_STATE || pesp01s->mqtt_connect)
    {
        if (pesp01s->uart_rx_callback != NULL)
        {
            // 调用用户回调函数
            pesp01s->uart_rx_callback(data, len);
        }
        if (pesp01s->receive_state == ESP_01S_RECV_PASSTHROUGH_STATE)
        {
            return 0;
        }
    }
     /* 检测没有请求命令 */
    if (pesp01s->request_state == ESP_01S_REQ_IDLE_STATE
    || pesp01s->request_state == ESP_01S_REQ_CPLT_STATE)
    {
        return 0;
    }
    /* 检测是否有帧头 "AT+" */
    if (pesp01s->receive_state == ESP_01S_RECV_IDLE_STATE)
    {
        if (data[0] == 'A' && data[1] == 'T' && data[2] == '+')
        {
            // 含有帧头,开始接收
            pesp01s->rxcnt = 0;
            pesp01s->receive_state = ESP_01S_RECV_START_STATE;
        }
        else return 0;
    }
    /* 接收数据，直到遇到结束符"OK\r\n */
    if (pesp01s->receive_state == ESP_01S_RECV_START_STATE)
    {
        if (ESP_01S_MQTT_RX_BUFFER_SIZE - pesp01s->rxcnt >= len) // 接收缓存没满 
        {
            memcpy(pesp01s->rxbuf + pesp01s->rxcnt, data, len);
            pesp01s->rxcnt += len;
        }
        else // 接收缓存已满
        {
            // pesp01s->receive_state = ESP_01S_RECV_ERROR_STATE;
            pesp01s->receive_state = ESP_01S_RECV_IDLE_STATE;
            pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
            debug_printf("esp01s_receive_error\n\r");
        }
        // 检测帧数据是否结束
        ptr = find_subData(data, len, (uint8_t*)ESP_01S_REQ_END, 4);
        if (ptr != NULL) // 检测到'OK\r\n'本次请求结束
        {
            // 接收完一帧数据，然后解析
            pesp01s->receive_state = ESP_01S_RECV_END_STATE;
        }
        else
        {
            ptr = find_subData(data, len, ESP_01S_REQ_ERROR, 5);
            if (ptr != NULL) // 检测到'ERROR'本次请求失败
            {
                pesp01s->receive_state = ESP_01S_RECV_IDLE_STATE;
                pesp01s->request_state = ESP_01S_REQ_ERROR_STATE;
            }
            return 0;
        }
    }
    /* 数据接收完成，开始解析数据 */
    if (pesp01s->receive_state != ESP_01S_RECV_END_STATE)
    {
        return 0;
    }
    data = pesp01s->rxbuf;
    len = pesp01s->rxcnt;
    // 解析esp01s返回的值
    switch (pesp01s->request_state)
    {
    case ESP_01S_REQ_STATE:
        pesp01s->request_state = ESP_01S_REQ_CPLT_STATE;
        break;
    case ESP_01S_REQ_WMODE_GET_STATE:
        // 获取无线模式
        state = strncmp((char *)data, ESP_01S_CMD_WMODE_GET, sizeof(ESP_01S_CMD_WMODE_GET)-1);
        if (state == 0)
        {
            // 解析无线模式的报文
            state = esp_01s_get_wirless_mode(data, len, &pesp01s->wirless_mode);
            if (state == 0) 
            {
                pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
                debug_printf("esp01s_wirless_mode:%d\n\r", pesp01s->wirless_mode);
                break;
            }
        }
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        break;
    case ESP_01S_REQ_IPSTA_GET_STATE:
        // 判断是否为IP状态请求的回复报文
        state = strncmp((char *)data, ESP_01S_CMD_IPSTA_GET, sizeof(ESP_01S_CMD_IPSTA_GET)-1);
        if (state == 0)
        {
            // 解析IP状态的报文
            state = esp01s_get_ip_state(data,
                                len,
                                pesp01s->ip_device,
                                pesp01s->ip_gateway,
                                pesp01s->ip_netmask);
            if (state == 0)
            {
                pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
                debug_printf("esp01s_ip_device:%s\n\r", pesp01s->ip_device);
                debug_printf("esp01s_ip_gateway:%s\n\r", pesp01s->ip_gateway);
                debug_printf("esp01s_ip_netmask:%s\n\r", pesp01s->ip_netmask);
                break;
            }
        }
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        break;
    case ESP_01S_REQ_PING_GET_STATE:
        // 判断是否为ping回复
        state = strncmp((char *)data, ESP_01S_CMD_PING, 7);
        if (state == 0)
        {
            // ping状态解析
            state = esp01s_get_ping_value(data, len, &pesp01s->ping);
            if (state == 0)
            {
                pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
                debug_printf("esp01s_ping:%d\n\r", pesp01s->ping);
                break;
            }
        }
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        break;
    case ESP_01S_REQ_CONNECT_STATE:
        // 判断TCP/UDP是否连接成功
        state = strncmp((char *)data, ESP_01S_CMD_CIPSTART, 11);
        if (state == 0)
        {
            state = esp01s_connect_ack(data, len);
            // 连接成功
            if (state == 0)
            {
                pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
                debug_printf("esp01s_cipstart_ok\n\r");
                break;
            }
        }
        // 连接失败
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        debug_printf("esp01s_cipstart_error\n\r");
        break;
    case ESP_01S_REQ_PASSTHROUGH_STATE:
        // 判断是否为开启透传成功
        state = strncmp((char *)data, ESP_01S_CMD_PASSTHROUGH, sizeof(ESP_01S_CMD_PASSTHROUGH)-1);
        if (state == 0)
        {
            // 开启透传成功,进入透传状态
            pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
            pesp01s->receive_state = ESP_01S_RECV_PASSTHROUGH_STATE;
            debug_printf("esp01s_passthrough_open\n\r");
            break;
        }
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE;
        break;
    case ESP_01S_REQ_JAP_STATE:
        // 判断是否为连接WIFI成功
        state = strncmp((char *)data, ESP_01S_CMD_JAP, 8);
        if (state == 0)
        {
            state = esp01s_get_jap_state(data, len);
            if (state == 0)
            {
                pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
                debug_printf("esp01s_wifi_connect_ok\n\r");
                break;
            }
        }
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        break;
    case ESP_01S_REQ_MQTT_CONNECT_STATE:
        // 判断是否为MQTT连接成功
        state = strncmp((char *)data, ESP_01S_CMD_MQTT_CONNECT, 11);
        if (state == 0)
        {
            pesp01s->request_state = ESP_01S_REQ_CPLT_STATE; // 完成请求，可以读取了
            pesp01s->mqtt_connect = 1;
        }
        break;
    default:
        debug_printf("error request_state:%d\n\r", pesp01s->request_state);
        pesp01s->request_state = ESP_01S_REQ_ERROR_STATE; // 请求失败
        break;
    }
    // 接收数据处理完毕，进入空闲状态
    if (pesp01s->receive_state == ESP_01S_RECV_END_STATE)
    {
        pesp01s->receive_state = ESP_01S_RECV_IDLE_STATE;
    }
    
	return 0;
}
